/*******************************************************************************
 *  Summary         : 同步配件订单接口
 *  Refer Object    :
 *  Author          : tianhui
 *  CreatedDate     : 2023-5-30
 *  Change Log      :
 *  version         : 1.0
 ******************************************************************************/
public without sharing class InterfaceCallOut_DMSSpToSAP {
    public static String endpoint = InterfaceUrl__mdt.getAll().get('SS71OrderToSAP').Value__c;
    public static String authorization = InterfaceUrl__mdt.getAll().get('ClaimSAPAuthorization').Value__c;
    /**
    * 同步配件订单方法
    * @Author   tianhui
    * @DateTime 2023-05-30
    */
    public static Map<String, String> syncSpToSAP(String recordId) {
        // Approval.UnlockResult ur = Approval.unlock(recordId);
        // 创建接口日志
        Interface_Log__c log  =  new Interface_Log__c(
            Interface_Name__c = '同步配件订单接口',
            Start_Time__c = Datetime.now().format('yyyy-MM-dd HH:mm:ss'),
            Client__c = 'SF',
            Servicer__c = 'SAP',
            IsCallSuccessful__c = true // 接口默认调用成功
        );
        //Attachment Collection
        List<Attachment> attList = new List<Attachment>();
        System.debug('开始进行同步配件订单');
        System.debug('endpoint:' + endpoint);
        System.debug('authorization:' + authorization);
        //创建返回信息
        Map<String, String> returnMap = new Map<String, String>();
        //根据订单id查询订单详细信息
        SS71Order__c order = [SELECT Id
                              , Name
                              , ContractCode__c //合同编号
                              , Incoterms__c //国际贸易条款
                              , Order__r.Name
                              , Order__r.SalesOrgCode__c
                              , Order__r.Code__c
                              , Order__r.OrderAddress__r.Address__c //详细地址
                              , Order__r.ExportCountry__c //出口国家
                              , Order__r.OrderAddress__r.Contatcts__c //联系人
                              , Order__r.OrderAddress__r.Telephone__c //电话
                              , Order__r.Handler__r.Name //业务员姓名
                              , Order__r.OrderType__c //订单类型
                              , CostCenter__c //成本中心
                              , Order__r.PaymentMethod__c //支付方式
                              , Order__r.SalesOrg__r.Name //销售组织名
                              , DealerCode__c //服务商编码
                              , Order__r.Handler__r.DepartmentCode__c//部门
                              , Order__r.CreatedDate
                              , Department__c //部门
                              , RequiredDeliveryDate__c //要求交货日期
                              , Order__c //订单号
                              , Order__r.Account__c //服务商编号
                              , Currency__c //币种
                              , SAPOrderNo__c //SAP订单号
                              , ProductionBaseCode__c //生成基地编码
                              , Order__r.Account__r.ServiceProviderSAPCode__c
                              , Order__r.RecordTypeId
                              FROM SS71Order__c
                              WHERE Id = :recordId];
        try {
            System.debug('查询到的Order:' + order);
            //推送SS71订单到Sap前，判断当前订单的Sapcode是否存在，不存在推送，存在不推送。
            if (!String.isBlank(order.SAPOrderNo__c)) {
                return null;
            }
            //查询全部SS71订单明细信息
            List<OrderDetails__c> orderDetailsList = [SELECT Id
                    , Name //明细名
                    , Qty__c //数量
                    , DiscountAmount__c
                    , ShippingAmount__c
                    , MaterialCode__r.MaterialSAPCode__c //物料Sap编号
                    FROM OrderDetails__c
                    WHERE SS71Order__c = :order.Id];
            System.debug('查询的SS71order信息:' + order);
            System.debug('查询到的orderDetailsList的信息:' + orderDetailsList);
            //创建需要传入接口的数据
            SpData outSpData = new SpData();
            // if (Rest_Utils.specSalesOrgStr.contains(order.Order__r.SalesOrgCode__c)) {
            //     //合同编号
            //     outSpData.bname = order.Order__r.Code__c;
            //     //合同子编号
            //     outSpData.bnameZ = order.Order__r.Code__c;
            // } else {
            //     //合同编号
            //     outSpData.bname = order.ContractCode__c;
            //     //合同子编号
            //     outSpData.bnameZ = order.ContractCode__c;
            // }

            //合同编号
            outSpData.bname = order.Order__r.Code__c;
            //合同子编号
            outSpData.bnameZ = order.Order__r.Code__c;
            //基地
            outSpData.ihrez = order.ProductionBaseCode__c;
            //业务员姓名
            outSpData.sasman = order.Order__r.Handler__r.Name;
            //配件类型
            // outSpData.zfg = order.Order__r.OrderType__c;
            outSpData.zfg = '配件';
            //凭证类别
            //if (order.Order__r.OrderType__c == '常规订单' || order.Order__r.OrderType__c == '众筹订单') {
            String PartsOrderId = Schema.SObjectType.Order__c.getRecordTypeInfosByDeveloperName().get('PartsOrder').getRecordTypeId();
            String CrowdfundingOrderId = Schema.SObjectType.Order__c.getRecordTypeInfosByDeveloperName().get('CrowdfundingOrder').getRecordTypeId();
            if ((order.Order__r.RecordTypeId == PartsOrderId || order.Order__r.RecordTypeid == CrowdfundingOrderId) && order.Order__r.OrderType__c != '索赔订单') {
                outSpData.vbtyp = '3';
                //销售凭证类型
                outSpData.auart = 'ZCOR';
            } else if (order.Order__r.OrderType__c == '') {
                outSpData.vbtyp = '4';
                //当订单类型为4时，需要给成本赋值
                outSpData.kostl = order.CostCenter__c;
                //销售凭证类型
                outSpData.auart = 'ZCFD';
            } else if (order.Order__r.RecordTypeId == PartsOrderId && order.Order__r.OrderType__c == '索赔订单') {
                outSpData.vbtyp = '5';
                //销售凭证类型
                outSpData.auart = 'ZCSP';
            }
            //支付方式
            outSpData.zterm = order.Order__r.PaymentMethod__c;
            //原始订单销售组织
            outSpData.vkorg = order.Order__r.SalesOrg__r.Name;
            //分销渠道
            outSpData.vtweg = '70';
            //产品组
            outSpData.spart = '20';
            //订单类型
            outSpData.vsnmrV = '1';
            //部门Code
            outSpData.vkbur = order.Order__r.Handler__r.DepartmentCode__c;
            //服务商编号
            outSpData.kunnr = order.Order__r.Account__r.ServiceProviderSAPCode__c;
            // outSpData.kunnr = '19000005'
            //原始订单要求交货日期
            if (Rest_Utils.specSalesOrgStr.contains(order.Order__r.SalesOrgCode__c)) {
                outSpData.audat = String.valueOf(System.today());
            } else {
                outSpData.audat = order.Order__r.CreatedDate.format('yyyyMMdd');
            }

            //国际贸易条款INCO1
            outSpData.inco1 = order.Incoterms__c;
            //inco2L
            outSpData.inco2L = order.Incoterms__c;
            //取PI中的收货地址+"/"+联系人+"/"+联系电话
            outSpData.headtxt = order.Order__r.ExportCountry__c + order.Order__r.OrderAddress__r.Address__c + '/' + order.Order__r.OrderAddress__r.Contatcts__c + '/' + order.Order__r.OrderAddress__r.Telephone__c; //必填  取PI中的收货地址+"/"+联系人+"/"+联系电话
            //订单币种
            outSpData.waerk = order.Currency__c;
            //zhead1
            if (Rest_Utils.specSalesOrgStr.contains(order.Order__r.SalesOrgCode__c)) {
                outSpData.zhead1 = '2';
            }
            //zhead2
            outSpData.zhead2 = 'ZDMS';

            //订单编号
            outSpData.zhead3 = order.Order__r.Name;
            //订单明细行
            List<SpItems> spItemsList = new List<SpItems>();
            for (OrderDetails__c item : orderDetailsList) {
                //创建明细对象
                SpItems spItems = new SpItems();
                //明细行ID
                spItems.detailId = item.Name;
                //打包方式
                spItems.zdbfs = '全散';
                //物料号
                spItems.matnr = item.MaterialCode__r.MaterialSAPCode__c;
                //以销售单位表示的累计订单数量
                spItems.kwmeng = String.valueOf(item.Qty__c);
                //计划行日期
                spItems.edatu = Datetime.now().format('yyyy-MM-dd HH:mm:ss');
                //折扣
                spItems.zkprice = item.DiscountAmount__c;
                //运费
                spItems.yfprice = item.ShippingAmount__c;
                //添加到集合中
                spItemsList.add(spItems);
            }
            outSpData.items = spItemsList;
            System.debug('需要传输的数据:' + outSpData);
            //开始调用接口
            HttpRequest request = new HttpRequest();
            //接口地址
            request.setEndpoint(endpoint);
            //请求方式
            request.setMethod('POST');
            //请求头部
            request.setHeader('Authorization', authorization + ' ' + InterfaceCallOut_GetSapToken.getSapToken());
            //请求头部
            request.setHeader('Content-Type', 'application/json');
            //请求token
            if (!Test.isRunningTest()) {
                request.setHeader('access_token', InterfaceCallOut_GetSapToken.getSapToken());
            }
            //请求数据
            request.setBody(JSON.serialize(outSpData));
            System.debug('请求数据的Json格式:' + JSON.serialize(outSpData));
            //接口调用开始时间
            log.Start_Time__c = Datetime.now().format('yyyy-MM-dd HH:mm:ss');
            //发送http请求
            Http http = new Http();
            HttpResponse response = http.send(request);
            //接口调用结束时间
            log.End_Time__c = Datetime.now().format('yyyy-MM-dd HH:mm:ss');
            //查看接口是否调用
            System.debug('statusCode:' + response.getStatusCode());
            if (JSON.serialize(outSpData).length() > 100000 || Test.isRunningTest()) {
                attList.add(
                    new Attachment(
                        Name = log.Interface_Name__c + '-request.txt',
                        ContentType = 'text/plain',
                        Body = Blob.valueOf(JSON.serialize(outSpData))
                    )
                );
            } else {
                log.Body__c = JSON.serialize(outSpData);
            }

            if (response.getStatusCode() == 200) {
                //获取接口返回信息
                Map<String, Object> responseMap = (Map<String, Object>)JSON.deserializeUntyped(response.getBody());
                System.debug('接口返回信息:' + responseMap);
                //获取状态码
                String evStatus = String.valueOf(responseMap.get('evStatus'));
                //获取返回的Id
                String vbeln = String.valueOf(responseMap.get('vbeln'));
                System.debug('evStatus:' + evStatus);
                System.debug(vbeln);
                if ('S'.equals(evStatus)) {
                    log.Exception_Msg__c = '接口调取成功';
                    log.IsCallSuccessful__c = true;
                    log.Resp_Result__c = response.getBody();
                    order.SAPOrderNo__c = vbeln;
                    order.SynchronizationStatus__c = '同步SAP成功';
                    UPDATE order;
                    returnMap.put('success', Label.DMSToSap1);
                } else {
                    order.SynchronizationStatus__c = '同步SAP失败';
                    UPDATE order;
                    log.Exception_Msg__c = '接口调取失败';
                    log.IsCallSuccessful__c = false;
                    log.Resp_Result__c = response.getBody();
                    returnMap.put('error', Label.DMSToSap2);
                }
            } else {
                log.Exception_Msg__c = '接口调取失败';
                log.IsCallSuccessful__c = false;
                returnMap.put('error', Label.ClaimAmount_prompt3);
            }
        } catch (Exception e) {
            System.debug('出现异常');
            System.debug('e.getMessage()@@@:' + e.getMessage());
            System.debug('e.getLineNumber()@@:' + e.getLineNumber());
            System.debug('e.getStackTraceString()@@:' + e.getStackTraceString());
            // 表示接口出现异常请求失败
            log.IsCallSuccessful__c = false;
            // 接口请求失败的原因
            log.Exception_Msg__c = e.getLineNumber() + e.getMessage();
            returnMap.put('error', Label.SystemError);
        } finally {
            System.debug('记录接口日志');
            insert log;
            if (attList.isEmpty()) {
                for (Attachment item : attList) {
                    item.ParentId = log.Id;
                }
                INSERT attList;
            }

        }
        return returnMap;


    }
    //内部类
    public class SpData {
        public String bname;    //必填  合同编号
        public String bnameZ;   //必填
        public String sasman;   //必填  业务员姓名
        public String zfg;      //必填  配件类型
        public String vbtyp;    //必填  凭证类别 ‘3’配件（|| 众筹），‘4’免费，‘5’（索赔）
        public String auart;    //必填  根据VBTYP字段赋值  配件ZCOR，免费ZCFD，索赔ZCSP
        public String kostl;    //成本中心(凭证为4需要填这个信息)
        public String zterm;    //必填  支付方式
        public String ihrez;    //必填
        public String vkorg;    //必填  原始订单销售组织
        public String vtweg;    //必填  分销渠道 默认70
        public String spart;    //必填  产品组 默认20
        public String vsnmrV;   //必填  订单类型（整车/配件）默认0
        public String vkbur;    //必填  部门Code
        public String vkgrp;    //
        public String kunnr;    //必填  服务商编号
        public String audat;    //必填  原始订单要求交货日期
        public String inco1;    //必填  国际贸易条款INCO1
        public String headtxt;  //必填  取PI中的收货地址+"/"+联系人+"/"+联系电话
        public String inco2L;   //
        public String waerk;    //必填  订单币种
        public String zhead1;   //
        public String zhead2;   //
        public String zhead3;   //
        public String zhead4;   //
        public String zhead5;   //
        public String zbgfs;    //
        public List<SpItems> items; //订单明细行
    }
    //内部类子对象
    public class SpItems {
        public String detailId; //必填  明细行ID
        public String zdbfs;    //必填  打包方式 '整车'  '半散'  '全散'
        public String upitem;   //
        public String matnr;    //必填  物料号
        public String kwmeng;   //必填  以销售单位表示的累计订单数量
        public String vrkme;    //
        public String werks;    //
        public String lgort;    //
        public String edatu;    //必填  计划行日期
        public String zr00;     //
        public String zitem1;   //
        public String zitem2;   //
        public String zitem3;   //
        public String zitem4;   //
        public String zitem5;   //
        public String upsl;     //
        public Decimal zkprice; //折扣
        public Decimal yfprice; //运费  折扣运费取SS71订单明细上分摊字段
    }
}